package com.acc.mobileappr.servlet;

import com.acc.mobileappr.constant.AppConstant;
import com.acc.mobileappr.entities.TrnMApprRequestEntity;
import com.acc.mobileappr.util.Util;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.regex.Pattern;


/**
 *  Receive notification from RIM, Servlet
 *  Abiel@ICN
 *
 */
public class ReceiveNotification extends HttpServlet {

    private static final EntityManagerFactory factory = Persistence.createEntityManagerFactory(AppConstant.PERSISTENCE_UNIT_MAREX);

    /**
     * Constructor
     */
    public ReceiveNotification() {

    }

    /**
     * process request
     *
     * @param request            request from RIM
     * @param response           response from us
     * @throws ServletException  exception on servlet process
     * @throws IOException       exception when IO operation is failed
     */
    void processRequest(HttpServletRequest request, HttpServletResponse response) {

        String pin = request.getHeader("X-RIM-Push-Destination");
        String pushId = request.getHeader("X-RIM-Push-ID");
        String pushStatus = request.getHeader("X-RIM-Push-Status");

        Util.print("Receiving Notification..");
        String x[] = pushId.split("-");
        EntityManager  em = factory.createEntityManager();

        try {

            if (pushStatus.equalsIgnoreCase("200")) {
                Util.success("Success from pushId "+x[0]+", pin="+pin);
                pushStatus = "S";
            } else {
                Util.error("Push Status: "+pushStatus+" from pushId "+x[0]+ " : "+AppConstant.getProperty("message.push."+pushStatus));
                pushStatus = "F";
            }
            
            //table trn_m_appr_request (pin & push_id and push_status)
            //change push status to S
            Query q = em.createQuery("select req from TrnMApprRequestEntity req where lower(req.pin) = ?1 and req.pushId=?2")
                    .setParameter(1, pin.toLowerCase())
                    .setParameter(2, x[0]);

            List<TrnMApprRequestEntity> lst = q.getResultList();

            if (!lst.isEmpty()) {

                em.getTransaction().begin();

                TrnMApprRequestEntity req = lst.get(0);
                Util.print("Setting push status on database for pin: "+req.getPin() +" to "+pushStatus);

                //TODO: Bad practice :( I dont like using SQL directly, but so far this is the best option

                Query q2 = em.createNativeQuery("UPDATE TRN_M_APPR_REQUEST SET PUSH_STATUS=?1 WHERE PIN=?2 AND PUSH_ID=?3")
                           .setParameter(1,pushStatus)
                           .setParameter(2,req.getPin())
                           .setParameter(3,req.getPushId());

                q2.executeUpdate();

                em.getTransaction().commit();

            } else {

                Util.error("User pin "+pin+" is not found in database.");

            }

        } catch (Exception e) {
            e.printStackTrace();
            Util.error(e.getMessage());

        } finally {

                em.close();
        }

        Util.print("End Receiving Notification.");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        processRequest(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        processRequest(req, resp);
    }

    /**
     * Returns a short description of the servlet.
     */
    public String getServletInfo() {
        return "Receive Notification Servlet";
    }

}
